package org.example.web;

import org.apache.commons.lang3.StringUtils;
import org.example.exception.RedisOperationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/redis")
public class RedisController {
  private static final Logger LOG = LoggerFactory.getLogger(RedisController.class);
  /** used for object persistence, usually unreadable. */
  @Autowired
  private RedisTemplate redisTemplate;
  /** used for string persistence, usually readable. */
  @Autowired
  private StringRedisTemplate stringRedisTemplate;

  @RequestMapping(value = "/del/{key}", method = RequestMethod.GET)
  public ResponseEntity<?> delKey(@PathVariable("key") String key) {
    if (StringUtils.isBlank(key)) {
      String message = "empty redis key input.";
      return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
    }
    //  if the key not exists, delete operation is useless.
    Boolean hasKey = stringRedisTemplate.hasKey(key);
    if (!hasKey) {
      String message = "can not find key: " + key + " , nothing will be delete.";
      return new ResponseEntity<>(message, HttpStatus.OK);
    }
    //  delete key in redis
    try {
      stringRedisTemplate.delete(key);
    } catch (Exception e) {
      LOG.error("delete redis key: " + key + " failed!", e);
      throw new RedisOperationException(e);
    }

    String message = "delete key: " + key + " in redis successfully.";
    return new ResponseEntity<>(message, HttpStatus.OK);
  }

  @RequestMapping(value = "/flush", method = RequestMethod.GET)
  public ResponseEntity<?> flush() {
    //  flush redis use jedis
    try {
      stringRedisTemplate.execute(
          (RedisCallback<Object>)
              connection -> {
                connection.flushDb();
                return true;
              });
    } catch (Exception e) {
      LOG.error("flush redis failed!", e);
      throw new RedisOperationException(e);
    }

    String message = "flush redis successfully.";
    return new ResponseEntity<>(message, HttpStatus.OK);
  }

  public RedisTemplate getRedisTemplate() {
    return redisTemplate;
  }

  public void setRedisTemplate(RedisTemplate redisTemplate) {
    this.redisTemplate = redisTemplate;
  }

  public StringRedisTemplate getStringRedisTemplate() {
    return stringRedisTemplate;
  }

  public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
    this.stringRedisTemplate = stringRedisTemplate;
  }
}
